package com.jch.learn.config;

import org.yaml.snakeyaml.Yaml;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

// yaml 配置文件
public class YamlConfigKit {

    private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\$\\{([^}]+)}");

    public static <T> T read(String filePath, Class<T> clazz) {
        Yaml yaml = new Yaml();
        // 1. 读取配置文件
        try (InputStream in = YamlConfigKit.class.getClassLoader().getResourceAsStream(filePath)) {
            if (in == null) {
                throw new FileNotFoundException(filePath);
            }
            Map<String, Object> configMap = yaml.loadAs(in, Map.class);
            // 2. 解析变量引用
            resolveVariables(configMap, configMap);
            // 3. 转换为目标对象
            return yaml.loadAs(yaml.dump(configMap), clazz);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 递归解析Map中的变量引用
     */
    @SuppressWarnings("unchecked")
    private static void resolveVariables(Map<String, Object> sourceMap, Map<String, Object> rootMap) {
        for (Map.Entry<String, Object> entry : sourceMap.entrySet()) {
            Object value = entry.getValue();
            if (value instanceof String) {
                // 处理字符串中的变量引用
                String resolvedValue = resolveString((String) value, rootMap);
                entry.setValue(resolvedValue);
            } else if (value instanceof Map) {
                // 递归处理子Map
                resolveVariables((Map<String, Object>) value, rootMap);
            }
        }
    }

    /**
     * 解析字符串中的变量引用
     */
    private static String resolveString(String value, Map<String, Object> rootMap) {
        Matcher matcher = VARIABLE_PATTERN.matcher(value);
        StringBuffer result = new StringBuffer();
        while (matcher.find()) {
            String variableKey = matcher.group(1);
            Object variableValue = getValueFromMap(rootMap, variableKey);

            if (variableValue != null) {
                matcher.appendReplacement(result, variableValue.toString());
            } else {
                // 保留原始值如果未找到引用
                matcher.appendReplacement(result, matcher.group(0));
            }
        }
        matcher.appendTail(result);
        return result.toString();
    }

    /**
     * 从Map中获取嵌套属性值，支持"parent.child"形式的键
     */
    @SuppressWarnings("unchecked")
    private static Object getValueFromMap(Map<String, Object> map, String key) {
        String[] keyParts = key.split("\\.");
        Object currentValue = map;

        for (String part : keyParts) {
            if (currentValue instanceof Map) {
                currentValue = ((Map<String, Object>) currentValue).get(part);
            } else {
                return null;
            }
            if (currentValue == null) {
                return null;
            }
        }
        return currentValue;
    }

}